// /* **********************************************************************************
//  *
//  * Copyright (c) Sky Sanders. All rights reserved.
//  * 
//  * This source code is subject to terms and conditions of the Microsoft Public
//  * License (Ms-PL). A copy of the license can be found in the license.htm file
//  * included in this distribution.
//  *
//  * You must not remove this notice, or any other, from this software.
//  *
//  * **********************************************************************************/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using SimpleRemoteControl.Configuration;
using SimpleRemoteControl.Data.Domain;
using SimpleRemoteControl.Data.Repositories;

namespace SimpleRemoteControl
{
    public static class BrowserControl
    {
        /// <summary>
        /// close=[all|browserKey[,browserKey]...]
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public static List<Browser> Close(string request)
        {
            string[] items = request.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            if (items.Length == 1 && items[0].ToLower() == "all")
            {
                List<string> req = new List<string>();
                Common.Config.BrowserList.ForEach(x => req.Add(x.Key));
                return Close(string.Join(",", req.ToArray()));
            }

            List<Browser> result = new List<Browser>();
            foreach (string key in items)
            {
                BrowserElement browserEl = Common.Config.Browsers[key];
                bool ok = browserEl != null && CloseCore(Common.Config.Browsers[key].Path);
                Browser browser = BrowserRepository.GetByKey(key) ?? new Browser { Key = key };
                browser.Description = ok ? "CLOSED" : "NOT FOUND";
                result.Add(browser);
            }

            return result;
        }

        /// <summary>
        /// open=url,[all|browserKey[,browserKey]...]
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public static List<Browser> Open(string request)
        {
            string[] items = request.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            string url = items[0];

            if (items.Length > 1 && items[1].ToLower().StartsWith("all"))
            {
                List<string> req = new List<string> { url };
                Common.Config.BrowserList.ForEach(x => req.Add(x.Key));
                return Open(string.Join(",", req.ToArray()));
            }

            List<Browser> result = new List<Browser>();
            for (int i = 1; i < items.Length; i++)
            {
                string key = items[i];
                bool ok = Common.Config.Browsers[key] != null && OpenCore(Common.Config.Browsers[key].Path, url);
                Browser browser = BrowserRepository.GetByKey(key) ?? new Browser { Key = key };
                browser.Description = ok ? "OPENED" : "NOT FOUND";
                result.Add(browser);
            }
            return result;
        }


        private static bool CloseCore(string browser)
        {
            try
            {
                switch (Common.Platform)
                {
                    case OS.Win:
                        ExecuteCommand("taskkill", String.Format("/F /T /IM {0}", String.Format("\"{0}\"", Path.GetFileName(browser))), true);
                        return true;
                    case OS.Osx:
                        ExecuteCommand("killall", String.Format("-m .*{0}", String.Format("'{0}'", Path.GetFileName(browser))), true);
                        return true;
                    case OS.Linux:
                        ExecuteCommand("pkill", String.Format("-f {0}", String.Format("{0}", Path.GetFileName(browser))), true);
                        return true;
                    default:
                        return false;
                }
            }
            catch
            {
                return false;
            }
        }

        public static bool OpenCore(string browser, string url)
        {
            try
            {
                switch (Common.Platform)
                {
                    case OS.Win:
                        ExecuteCommand(String.Format("\"{0}\"", browser), String.Format("\"{0}\"", url), false);
                        return true;
                    case OS.Osx:
                        ExecuteCommand("open", String.Format("-a {0} {1}", String.Format("'{0}'", browser), String.Format("'{0}'", url)), false);
                        return true;
                    case OS.Linux:
                        ExecuteCommand(String.Format("{0}", browser), String.Format("{0}", url), false);
                        return true;
                    default:
                        return false;
                }
            }
            catch
            {
                return false;
            }
        }

        private static void ExecuteCommand(string cmd, string args, bool swallow)
        {
            try
            {
                Process proc = new Process
                {
                    StartInfo = new ProcessStartInfo
                    {
                        FileName = cmd,
                        Arguments = args,
                        CreateNoWindow = true,
                        ErrorDialog = false,
                        UseShellExecute = false
                    }
                };
                proc.Start();
            }
            catch (Exception up)
            {
                if (!swallow)
                {
                    throw (up);
                }
            }
        }
    }
}